package com.mlnx.netty.base;

import com.mlnx.common.utils.MyLog;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * Created by amanda.shan on 2019/10/10.
 */
public class DeviceNettyServer implements Server {

    MyLog log = MyLog.getLog(getClass());

    private EventLoopGroup bossGroup;
    private EventLoopGroup workGroup;

    private String serverName;

    private ChannelInitializer channelInitializer;
    private int port;

    private ChannelFuture channelFuture;

    public DeviceNettyServer(EventLoopGroup bossGroup, EventLoopGroup workGroup, String serverName) {
        this.bossGroup = bossGroup;
        this.workGroup = workGroup;
        this.serverName = serverName;
    }

    @Override
    public void start(ChannelInitializer channelInitializer, int port) throws Exception {
        this.channelInitializer = channelInitializer;
        this.port = port;
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workGroup).channel(NioServerSocketChannel.class)
                    // .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(channelInitializer).option(ChannelOption.SO_BACKLOG, 1024)
                    .option(ChannelOption.TCP_NODELAY,true)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            channelFuture = b.bind(port).sync(); // (7)
            log.info("{} 服务器启动 端口：{}", serverName, port);
        } finally {
            // 在jvm关闭的时候执行
            Runtime.getRuntime().addShutdownHook(new Thread() {
                @Override
                public void run() {
                    shutdown();
                }
            });
        }
    }

    @Override
    public void restart() throws Exception {

        shutdown();
        start(channelInitializer, port);
    }

    @Override
    public void shutdown() {

        log.info("{} 停止运行", serverName);

        if (channelFuture != null) {
            channelFuture.channel().close().syncUninterruptibly();
            channelFuture = null;
        }

    }
}
